﻿(function(){
	/*
	 * 滚动分页组件，使用改组件需要满足条件：
	 * 1.数据绑定组件，
	 * 2.毎行的高度一致
	 * 3.服务端请求模式支持范围查询和排序
	 * 4.静态数据模式必须有实现data filter委托方法
	*/
	$.fn.scrollLoad = function(op){
		op = $.extend({
			target:null,//需要做滚动分页的容器对象
			itemHeight:null,//单元高度
			pageInf:null,
			mode:null,		//分页模式'ajax':ajax请求模式；'filter':数据过滤模式
			dataParam:null, //数据参数ajax或者是data filter委托方法
			showTip:true,
			delay:200,
			fnScrollStart:null, //滚动开始执行方法
			fnTriggeOver:null, 	//捕获超出范围，触发加载事件的方法
			fnScrollEnd:null,	//滚动结束执行方法
			fnLoad : null	//重写加载回调方法
		},op);
		
		var showCount = parseInt(this.height() / op.itemHeight + 1),
			target = $(op.target).height(op.pageInf.total * op.itemHeight),
			//插入滚动高度设置的空区域
			topPlace = $.create('div','ccay-scrollLoad-topPlace').prependTo(target),
			times = 0,fnInterval,top,start,end,tip,pos;
			
		op.pageInf.showStart = 0;
		op.pageInf.showEnd = 0;
		op.showTip && (tip = scrollLoad.getTip());
		//参加参数来设置ajax
		scrollLoad.setDataFilter(op);
		
		this.scroll(function(e){
			var scroller = $(this);
			top = scroller.scrollTop();
			start = parseInt(top / op.itemHeight) + 1;
			end = start + showCount;
			//缓存页面开始和结束位置
			op.pageInf.showStart = start;
			op.pageInf.showEnd = end;
			op.showTip && (pos = scrollLoad.setTip(scroller,tip,top / op.itemHeight + 1 - start > 0.9 ? start + 1 : start,top,pos));
			//计数器置零
   			times = 0;
   			//触发区域后的回调
   			op.fnTriggeOver && (end > op.pageInf.end || start < op.pageInf.start) && op.fnTriggeOver(scroller,start,end,top);
   			
			if(fnInterval == null){
				op.fnScrollStart && op.fnScrollStart(scroller,start,end,top);
	   			fnInterval = setInterval(function(){
	   				if(times > 1)
	   				{
	   					times = 0;
	   					var isLoad;
	   					//判断是否超出当前界限
	   					if(end > op.pageInf.end || start < op.pageInf.start)
	   					{
	   						isLoad = true;
	   						//计算位置执行，执行加载事件
	   						scrollLoad.setPosition(op.pageInf,start,end).load(op,topPlace);
	   					}
	   					if(op.showTip)
						{
		   					tip.fadeOut(300);
		   					pos = null;
						}
		   				clearInterval(fnInterval);
		   				fnInterval = null;
		   				op.fnScrollEnd && op.fnScrollEnd(scroller,op.pageInf,isLoad);
	   				}
	   				else
	   					times++;
	   			},op.delay || 10);
	   		}
		});
		var self = this;
		//返回滚动分页的回调对象
		return {
			//设置记录总数
			setTotal:function(total){
				if(total != op.pageInf.total)
				{
					op.pageInf.total = total;
					target.height(total * op.itemHeight);
				}
				// 重设滚动加载的高度
				var pageInf = op.pageInf,
					dataHeight = topPlace.next().height(),
					// 将上次占位高度缓存
					topPlaceHeight = topPlace.height(),
					normalHeight,
					changeHeight;
				if (pageInf.end > pageInf.total) {
					normalHeight = (pageInf.total - pageInf.start + 1) * op.itemHeight
				} else {
					normalHeight = (pageInf.end - pageInf.start + 1) * op.itemHeight
				}
				if (op._changeHeight) {
					changeHeight = dataHeight - op._changeHeight - normalHeight;
					delete op._changeHeight;
				} else {
					changeHeight = dataHeight - normalHeight
				}
				if (changeHeight > 0 && top > 0) {
					topPlaceHeight -= changeHeight;
					op._changeHeight = changeHeight;
					topPlace.height(topPlaceHeight);
				}
			},
			//重置
			reset:function(){
				op.pageInf.total = 0;
	   			op.pageInf.start = 1;
	   			op.pageInf.end = op.pageInf.pageSize;
	   			self.scrollTop(0);
				scrollLoad.setTopPlace(op,topPlace);
				target.height(0);
			},
			// 重新加载
			load:function(){
				//执行load
				op.fnLoad(op.pageInf);
				scrollLoad.setTopPlace(op,topPlace);
			}
		};
	}
	var scrollLoad = {
		getTip:function(){
			var tip = $('#scrollLoad_tip');
			tip.length || (tip = $.create('div',null,'scrollLoad_tip').appendTo(document.body));
			return tip;
		},
		//设置滚动位置的提示
		setTip:function(scroller,tip,start,top,pos){
			//获取位置
			if(pos == null)
			{
				pos = scroller.offset();
				pos.right = $(document.body).width() - pos.left - scroller.width() + 20;
			}
			//根据比例计算滚动块位置
			var ctop = pos.top + top / scroller[0].scrollHeight * (scroller.height() - 40) + 10;
			tip.css({right:pos.right,top:ctop}).text(start).show();
			return pos;
		},
		//设置范围请求
		setDataFilter:function(op){
			if(op.mode)
			{
				if(op.mode == "ajax")
				{
					op.dataParam.setAjax = function(ajax){
						var url = ajax.url;
		       			if (url) {
		       				if (url.indexOf("{0}") > 0) {
		       					ajax.url = url.formatText(op.pageInf.start,op.pageInf.end,op.pageInf.total);  
		       				} else {
		       					op.pageInf.orderBy = "${orderBy}";
		       					if(url.indexOf("${filter}")>0){
		       						op.pageInf.filter = "${filter}"
		       					}
		       					ajax.url = url.formatField(op.pageInf);
		       				}
		       			}
					}
				}
				else{
					op.dataParam.add(function(){
						return scrollLoad.getRangeData(this,op.pageInf);
					});
				}
			}
		},
		//根据范围获取数据
		getRangeData:function(data,pageInf){
			
			if(data && data.length > pageInf.start - 1)
				return data.slice(pageInf.start - 1,pageInf.end);
		},
		//设置数据位置
		setPosition:function(pageInf,start,end)
		{
			
			pageInf.start = (parseInt(start / pageInf.pageSize) - (start % pageInf.pageSize ? 0 : 1)) * pageInf.pageSize + 1;
			pageInf.end =  pageInf.start + pageInf.pageSize * 2 - 1;
			//判断是否是最后一页数据
//			if(pageInf.end > pageInf.total && pageInf.start > pageInf.pageSize)
//			{
//				pageInf.start -= pageInf.pageSize;
//			}
			return this;
		},
		//加载事件
		load:function(op,topPlace){
			//执行load
			op.fnLoad(op.pageInf);
			this.setTopPlace(op,topPlace);
		},
		setTopPlace:function(op,topPlace){
			//设置占位高度
			var top = (op.pageInf.start - 1) * op.itemHeight;
			topPlace.height(top);
		}
	};
})();